package com.feonix.common.basedao;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.BooleanConverter;
import org.apache.commons.beanutils.converters.ByteConverter;
import org.apache.commons.beanutils.converters.DoubleConverter;
import org.apache.commons.beanutils.converters.FloatConverter;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.beanutils.converters.LongConverter;
import org.apache.commons.beanutils.converters.ShortConverter;

import com.feonix.common.service.EntityORMService;
import com.feonix.common.util.SpringUtil;

public class EntityManager {

	private static Map<Class<?>, Entity> classes = new HashMap<Class<?>, Entity>();

	/**
	 * 实体与表以及字段的映射关系
	 */
	private static Map<Class<?>, Map<SqlType, String>> entities = new HashMap<Class<?>, Map<SqlType, String>>();

	/**
	 * 实体预生成的sql
	 */
	private static List<Class<?>> entitiesSql = new ArrayList<Class<?>>();

	public static void init() {
		classes.clear();
		entities.clear();
		for (Class<?> clazz : entitiesSql) {
			EntityResolving.resolving(clazz);
			EntitySqlBuilder.buildSql(clazz);
		}
		ConvertUtils.register(new IntegerConverter(null), Integer.class);
		ConvertUtils.register(new DoubleConverter(null), Double.class);
		ConvertUtils.register(new FloatConverter(null), Float.class);
		ConvertUtils.register(new ByteConverter(null), Byte.class);
		ConvertUtils.register(new LongConverter(null), Long.class);
		ConvertUtils.register(new ShortConverter(null), Short.class);
		ConvertUtils.register(new BooleanConverter(null), Boolean.class);
	}

	public static void addClass(Class<?> clazz) {
		if ((clazz != null) && (!(entitiesSql.contains(clazz))))
			entitiesSql.add(clazz);
	}

	public static Map<Class<?>, Entity> getEntities() {
		return classes;
	}

	public static void addEntity(Class<?> clazz, Entity entity) {
		if ((clazz == null) || (clazz == null)) {
			return;
		}
		classes.put(clazz, entity);
	}

	public static void addEntitySql(Class<?> clazz, Map<SqlType, String> sql) {
		entities.put(clazz, sql);
	}

	public static Entity getEntity(Class<?> clazz) {
		return ((Entity) classes.get(clazz));
	}

	public static Map<SqlType, String> getEntitySql(Class<?> clazz) {
		return entities.get(clazz);
	}

	public static Collection<Map<SqlType, String>> getEntitiesSql() {
		return entities.values();
	}

	public static String buildInsertSql(Class<?> clazz, String tableName) {
		String str = null;
		try {
			str = EntitySqlBuilder.buildInsertSql(getCopyEntity(clazz, tableName));
		} catch (Exception exception) {
		}
		return str;
	}

	public static String buildUpdateSql(Class<?> clazz, String tableName) {
		String str = null;
		try {
			str = EntitySqlBuilder.buildUpdateSql(getCopyEntity(clazz, tableName));
		} catch (Exception exception) {
		}
		return str;
	}

	public static String buildSelectSql(Class<?> clazz, String tableName) {
		String str = null;
		try {
			str = EntitySqlBuilder.buildSelectSql(getCopyEntity(clazz, tableName));
		} catch (Exception exception) {
		}
		return str;
	}

	public static String buildSelectFromIdSql(Class<?> clazz, String tableName) {
		String str = null;
		try {
			str = EntitySqlBuilder.buildSelectFromIdSql(getCopyEntity(clazz, tableName));
		} catch (Exception exception) {
		}
		return str;
	}

	public static String buildDeleteSql(Class<?> clazz, String tableName) {
		String str = null;
		try {
			str = EntitySqlBuilder.buildDeleteSql(getCopyEntity(clazz, tableName));
		} catch (Exception exception) {
		}
		return str;
	}

	public static String buildDeleteFromIdsSql(Class<?> clazz, String tableName) {
		String str = null;
		try {
			str = EntitySqlBuilder.buildDeleteFromIdsSql(getCopyEntity(clazz, tableName));
		} catch (Exception exception) {
		}
		return str;
	}

	public static String buildTableSql(Class<?> clazz, String tableName) {
		String str = null;
		try {
			str = EntitySqlBuilder.buildTableSql(getCopyEntity(clazz, tableName));
		} catch (Exception exception) {
		}
		return str;
	}

	public static String buildSeq(Class<?> clazz, String tableName) {
		String str = null;
		try {
			str = EntitySqlBuilder.buildSeq(getCopyEntity(clazz, tableName));
		} catch (Exception exception) {
		}
		return str;
	}

	public static String buildTrigger(Class<?> clazz, String tableName) {
		String str = null;
		try {
			str = EntitySqlBuilder.buildTrigger(getCopyEntity(clazz, tableName));
		} catch (Exception exception) {
		}
		return str;
	}

	public static String enableSeq(Class<?> clazz, String tableName) {
		String str = null;
		try {
			str = EntitySqlBuilder.enableSeq(getCopyEntity(clazz, tableName));
		} catch (Exception exception) {
		}
		return str;
	}

	public static String removeSeq(Class<?> clazz, String tableName) {
		String str = null;
		try {
			str = EntitySqlBuilder.removeSeq(getCopyEntity(clazz, tableName));
		} catch (Exception exception) {
		}
		return str;
	}

	public static String disableSeq(Class<?> clazz, String tableName) {
		String str = null;
		try {
			str = EntitySqlBuilder.disableSeq(getCopyEntity(clazz, tableName));
		} catch (Exception localException) {
		}
		return str;
	}

	private static Entity getCopyEntity(Class<?> clazz, String tableName) {
		Entity entity = getEntity(clazz);
		Entity cloneEntity = entity.clone();
		cloneEntity.setTableName(tableName);
		return cloneEntity;
	}

	public static void checkTableAndCreate() {
		EntityORMService entityORMService = SpringUtil.getBean(EntityORMService.class);
		Map<Class<?>, Entity> entities = getEntities();
		Set<Class<?>> ketSet = entities.keySet();
		for (Class<?> clazz : ketSet) {
			Entity entity = entities.get(clazz);
			entityORMService.addTableBeforeCheck(clazz, entity);
		}
	}

}
